/** 
 * Project Name:qfhy 
 * File Name:DateUtils.java 
 * Package Name:com.wf.qfhy.utils 
 * Date:2017年4月20日下午3:50:53 
 * Copyright (c) 2017, wxwj All Rights Reserved. 
 */

package com.wf.qfhy.utils;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;

import com.google.common.collect.Lists;

/**
 * @ClassName: DateUtils
 * @Description: 日期工具类, 继承org.apache.commons.lang3.time.DateUtils类
 * @author 王飞
 * @date 2017年4月20日 下午3:50:53
 * 
 */
public class QfDateUtils extends DateUtils {

	private static String[] parsePatterns = { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
			"yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss",
			"yyyy.MM.dd HH:mm", "yyyy.MM" };

	/**
	 * 得到当前日期字符串 格式（yyyy-MM-dd）
	 */
	public static String getDate() {
		return getDate("yyyy-MM-dd");
	}

	/**
	 * 得到当前日期字符串 格式（yyyy-MM-dd） pattern可以为："yyyy-MM-dd" "HH:mm:ss" "E"
	 */
	public static String getDate(String pattern) {
		return DateFormatUtils.format(new Date(), pattern.toString());
	}

	/**
	 * 得到日期字符串 默认格式（yyyy-MM-dd） pattern可以为："yyyy-MM-dd" "HH:mm:ss" "E"
	 */
	public static String formatDate(Date date, Object... pattern) {
		String formatDate = null;
		if (pattern != null && pattern.length > 0) {
			formatDate = DateFormatUtils.format(date, pattern[0].toString());
		} else {
			formatDate = DateFormatUtils.format(date, "yyyy-MM-dd");
		}
		return formatDate;
	}

	/**
	 * 得到日期时间字符串，转换格式（yyyy-MM-dd HH:mm:ss）
	 */
	public static String formatDateTime(Date date) {
		return formatDate(date, "yyyy-MM-dd HH:mm:ss");
	}

	/**
	 * 得到当前时间字符串 格式（HH:mm:ss）
	 */
	public static String getTime() {
		return formatDate(new Date(), "HH:mm:ss");
	}

	/**
	 * 得到当前日期和时间字符串 格式（yyyy-MM-dd HH:mm:ss）
	 */
	public static String getDateTime() {
		return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss");
	}

	/**
	 * 得到当前年份字符串 格式（yyyy）
	 */
	public static String getYear() {
		return formatDate(new Date(), "yyyy");
	}

	public static String getYear(Date date) {
		return formatDate(date, "yyyy");
	}

	public static String getYear(String dateString) {
		return formatDate(dateString == null ? new Date() : parseDate(dateString), "yyyy");
	}

	/**
	 * 得到当前月份字符串 格式（MM）
	 */
	public static String getMonth() {
		return formatDate(new Date(), "MM");
	}

	public static String getMonth(Date date) {
		return formatDate(date, "M");
	}

	public static String getMonth(String dateString) {
		return formatDate(dateString == null ? new Date() : parseDate(dateString), "M");
	}

	/**
	 * 得到当天字符串 格式（dd）
	 */
	public static String getDay() {
		return formatDate(new Date(), "dd");
	}

	/**
	 * 得到当前星期字符串 格式（E）星期几
	 */
	public static String getWeek() {
		return formatDate(new Date(), "E");
	}

	/**
	 * 获取指定日期是星期几 参数为null时表示获取当前日期是星期几
	 * 
	 * @param date
	 * @return
	 */
	public static String getWeekOfDate(Date date) {
		String[] weekOfDays = { "7", "1", "2", "3", "4", "5", "6" };
		Calendar calendar = Calendar.getInstance();
		if (date != null) {
			calendar.setTime(date);
		}
		int w = calendar.get(Calendar.DAY_OF_WEEK) - 1;
		if (w < 0) {
			w = 0;
		}
		return weekOfDays[w];
	}

	/**
	 * 日期型字符串转化为日期 格式 { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm",
	 * "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy.MM.dd",
	 * "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm" }
	 */
	public static Date parseDate(Object str) {
		if (str == null) {
			return null;
		}
		try {
			return parseDate(str.toString(), parsePatterns);
		} catch (ParseException e) {
			return null;
		}
	}

	/**
	 * 获取过去的天数
	 * 
	 * @param date
	 * @return
	 */
	public static long pastDays(Date date) {
		long t = new Date().getTime() - date.getTime();
		return t / (24 * 60 * 60 * 1000);
	}

	/**
	 * 获取过去的小时
	 * 
	 * @param date
	 * @return
	 */
	public static long pastHour(Date date) {
		long t = new Date().getTime() - date.getTime();
		return t / (60 * 60 * 1000);
	}

	/**
	 * 获取过去的分钟
	 * 
	 * @param date
	 * @return
	 */
	public static long pastMinutes(Date date) {
		long t = new Date().getTime() - date.getTime();
		return t / (60 * 1000);
	}

	/**
	 * 转换为时间（天,时:分:秒.毫秒）
	 * 
	 * @param timeMillis
	 * @return
	 */
	public static String formatDateTime(long timeMillis) {
		long day = timeMillis / (24 * 60 * 60 * 1000);
		long hour = (timeMillis / (60 * 60 * 1000) - day * 24);
		long min = ((timeMillis / (60 * 1000)) - day * 24 * 60 - hour * 60);
		long s = (timeMillis / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
		long sss = (timeMillis - day * 24 * 60 * 60 * 1000 - hour * 60 * 60 * 1000 - min * 60 * 1000 - s * 1000);
		return (day > 0 ? day + "," : "") + hour + ":" + min + ":" + s + "." + sss;
	}

	/**
	 * 获取两个日期之间的天数
	 * 
	 * @param before
	 * @param after
	 * @return
	 */
	public static double getDistanceOfTwoDate(Date before, Date after) {
		long beforeTime = before.getTime();
		long afterTime = after.getTime();
		return (afterTime - beforeTime) / (1000 * 60 * 60 * 24);
	}

	/**
	 * 获取两个日期之间的分钟数
	 * 
	 * @Author keeny
	 * @Title: getDistanceMinutesOfTwoDate
	 * @Description: 获取两个日期之间的分钟数
	 * @param @param
	 *            before
	 * @param @param
	 *            after
	 * @param @return
	 *            设定参数
	 * @return double 返回类型
	 */
	public static long getDistanceMinutesOfTwoDate(Date before, Date after) {
		long beforeTime = before.getTime();
		long afterTime = after.getTime();
		return (afterTime - beforeTime) / (1000 * 60);
	}

	/**
	 * 取得季度月
	 * 
	 * @param date
	 * @return
	 */
	public static Date[] getSeasonDate(Date date) {
		Date[] season = new Date[3];

		Calendar c = Calendar.getInstance();
		c.setTime(date);

		int nSeason = getSeason(date);
		if (nSeason == 1) {// 第一季度
			c.set(Calendar.MONTH, Calendar.JANUARY);
			season[0] = c.getTime();
			c.set(Calendar.MONTH, Calendar.FEBRUARY);
			season[1] = c.getTime();
			c.set(Calendar.MONTH, Calendar.MARCH);
			season[2] = c.getTime();
		} else if (nSeason == 2) {// 第二季度
			c.set(Calendar.MONTH, Calendar.APRIL);
			season[0] = c.getTime();
			c.set(Calendar.MONTH, Calendar.MAY);
			season[1] = c.getTime();
			c.set(Calendar.MONTH, Calendar.JUNE);
			season[2] = c.getTime();
		} else if (nSeason == 3) {// 第三季度
			c.set(Calendar.MONTH, Calendar.JULY);
			season[0] = c.getTime();
			c.set(Calendar.MONTH, Calendar.AUGUST);
			season[1] = c.getTime();
			c.set(Calendar.MONTH, Calendar.SEPTEMBER);
			season[2] = c.getTime();
		} else if (nSeason == 4) {// 第四季度
			c.set(Calendar.MONTH, Calendar.OCTOBER);
			season[0] = c.getTime();
			c.set(Calendar.MONTH, Calendar.NOVEMBER);
			season[1] = c.getTime();
			c.set(Calendar.MONTH, Calendar.DECEMBER);
			season[2] = c.getTime();
		}
		return season;
	}

	/**
	 * 根据季度值 获取季度所对应的月份
	 * 
	 * @Author keeny
	 * @Title: getSeasonDate
	 * @Description: 根据季度值 获取季度所对应的月份
	 * @param @param
	 *            nSeason
	 * @param @return
	 *            设定参数
	 * @return Date[] 返回类型
	 */
	public static Date[] getSeasonDate(Integer nSeason) {
		Date[] season = new Date[3];

		Calendar c = Calendar.getInstance();
		String year = getYear();
		int month = (nSeason - 1) * 3 + 1;
		c.setTime(parseDate(year + '-' + month));

		if (nSeason == 1) {// 第一季度
			c.set(Calendar.MONTH, Calendar.JANUARY);
			season[0] = c.getTime();
			c.set(Calendar.MONTH, Calendar.FEBRUARY);
			season[1] = c.getTime();
			c.set(Calendar.MONTH, Calendar.MARCH);
			season[2] = c.getTime();
		} else if (nSeason == 2) {// 第二季度
			c.set(Calendar.MONTH, Calendar.APRIL);
			season[0] = c.getTime();
			c.set(Calendar.MONTH, Calendar.MAY);
			season[1] = c.getTime();
			c.set(Calendar.MONTH, Calendar.JUNE);
			season[2] = c.getTime();
		} else if (nSeason == 3) {// 第三季度
			c.set(Calendar.MONTH, Calendar.JULY);
			season[0] = c.getTime();
			c.set(Calendar.MONTH, Calendar.AUGUST);
			season[1] = c.getTime();
			c.set(Calendar.MONTH, Calendar.SEPTEMBER);
			season[2] = c.getTime();
		} else if (nSeason == 4) {// 第四季度
			c.set(Calendar.MONTH, Calendar.OCTOBER);
			season[0] = c.getTime();
			c.set(Calendar.MONTH, Calendar.NOVEMBER);
			season[1] = c.getTime();
			c.set(Calendar.MONTH, Calendar.DECEMBER);
			season[2] = c.getTime();
		}
		return season;
	}

	/**
	 * 获取某个季度内的第一个月份到传入当前月份的数组
	 * 
	 * @Author keeny
	 * @Title: getSeasonFirstMonthToCurrentMonth
	 * @Description: 获取某个季度内的第一个月份到传入当前月份的数组
	 * @param @param
	 *            date
	 * @param @return
	 *            设定参数
	 * @return String[] 返回类型
	 */
	public static String[] getSeasonFirstMonthToCurrentMonth(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);

		int nSeason = getSeason(date);
		int firstMonthVal = (nSeason - 1) * 3 + 1;
		int monthVal = Integer.parseInt(formatDate(date, "M"));
		int diff = monthVal - firstMonthVal;

		String[] monthArr = new String[diff + 1];

		int index = 0;
		for (int i = firstMonthVal; i <= monthVal; i++) {
			monthArr[index] = String.valueOf(i);
			index++;
		}

		return monthArr;
	}

	/**
	 * 取得年度月
	 * 
	 * @param date
	 * @return
	 */
	public static Date[] getYearDate() {
		Date[] year = new Date[3];

		Calendar c = Calendar.getInstance();

		c.set(Calendar.MONTH, Calendar.JANUARY);
		year[0] = c.getTime();
		c.set(Calendar.MONTH, Calendar.FEBRUARY);
		year[1] = c.getTime();
		c.set(Calendar.MONTH, Calendar.MARCH);
		year[2] = c.getTime();
		c.set(Calendar.MONTH, Calendar.APRIL);
		year[3] = c.getTime();
		c.set(Calendar.MONTH, Calendar.MAY);
		year[4] = c.getTime();
		c.set(Calendar.MONTH, Calendar.JUNE);
		year[5] = c.getTime();
		c.set(Calendar.MONTH, Calendar.JULY);
		year[6] = c.getTime();
		c.set(Calendar.MONTH, Calendar.AUGUST);
		year[7] = c.getTime();
		c.set(Calendar.MONTH, Calendar.SEPTEMBER);
		year[8] = c.getTime();
		c.set(Calendar.MONTH, Calendar.OCTOBER);
		year[9] = c.getTime();
		c.set(Calendar.MONTH, Calendar.NOVEMBER);
		year[10] = c.getTime();
		c.set(Calendar.MONTH, Calendar.DECEMBER);
		year[11] = c.getTime();
		return year;
	}

	/**
	 * 
	 * 1 第一季度 2 第二季度 3 第三季度 4 第四季度
	 * 
	 * @param date
	 * @return
	 */
	public static int getSeason(Date date) {

		int season = 0;

		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int month = c.get(Calendar.MONTH);
		switch (month) {
		case Calendar.JANUARY:
		case Calendar.FEBRUARY:
		case Calendar.MARCH:
			season = 1;
			break;
		case Calendar.APRIL:
		case Calendar.MAY:
		case Calendar.JUNE:
			season = 2;
			break;
		case Calendar.JULY:
		case Calendar.AUGUST:
		case Calendar.SEPTEMBER:
			season = 3;
			break;
		case Calendar.OCTOBER:
		case Calendar.NOVEMBER:
		case Calendar.DECEMBER:
			season = 4;
			break;
		default:
			break;
		}
		return season;
	}

	/**
	 * 获取一年内某两个月之间的月份
	 * 
	 * @Author keeny
	 * @Title: getMonthsBetweenTwoDatesInOneYear
	 * @Description: 获取一年内某两个月之间的月份
	 * @param @param
	 *            date1 yyyy-MM
	 * @param @param
	 *            date2 yyyy-MM
	 * @param @return
	 *            设定参数
	 * @return List<Date> 返回类型
	 */
	public static List<Date> getMonthsBetweenTwoDatesInOneYear(Date date1, Date date2) {
		List<Date> dateList = Lists.newArrayList();
		Calendar dd = Calendar.getInstance();
		dd.setTime(date1);
		while (dd.getTime().before(date2)) {
			dateList.add(dd.getTime());
			dd.add(Calendar.MONTH, 1);
		}
		return dateList;
	}

	/**
	 * 获取间隔时间，包含start,包含end
	 */
	public static List<String> getDateMonths(Date start, Date end) {

		List<Date> list = new ArrayList<Date>();

		List<String> newlist = new ArrayList<String>();

		if (start != null && end != null) {
			Calendar calendar = Calendar.getInstance();
			Calendar calendarEND = Calendar.getInstance();
			calendar.setTime(getTrimeDate(start));
			calendarEND.setTime(getTrimeDate(end));
			while (calendar.before(calendarEND) || calendar.equals(calendarEND)) {
				list.add(calendar.getTime());
				calendar.add(Calendar.MONTH, 1);
			}
		}

		for (Date date : list) {
			newlist.add(new SimpleDateFormat("yyyy-MM-dd").format(date));
		}
		return newlist;

	}

	/**
	 * 取年月
	 */
	public static Date getTrimeDate(Date date) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
		try {
			sdf.parse(sdf.format(date));
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return date;
	}

	/**
	 * 获取上个月
	 * 
	 * @Author keeny
	 * @Title: getLastMonth
	 * @Description: 获取上个月
	 * @param @return
	 *            设定参数
	 * @return Date 返回类型
	 */
	public static Date getLastMonth() {
		Calendar c = Calendar.getInstance();// 获取当前日期
		c.add(Calendar.MONTH, -1);
		c.set(Calendar.DAY_OF_MONTH, 1);// 设置为1号,当前日期既为本月第一天

		return c.getTime();
	}

	// 获得上年第一天的日期 *
	public static String getLastYear() {
		Date date = new Date();
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy");// 可以方便地修改日期格式
		String years = dateFormat.format(date);
		int years_value = Integer.parseInt(years);
		years_value--;
		return years_value + "";
	}

	/**
	 * 获取下一个月份
	 * 
	 * @Author keeny
	 * @Title: getNextMonth
	 * @Description: 获取下一个月份
	 * @param @param
	 *            date
	 * @param @return
	 *            设定参数
	 * @return Date 返回类型
	 */
	public static Date getNextMonth(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.MONTH, 1);
		return c.getTime();
	}

	/**
	 * 获取当天日期最后的时间,传入格式为2017-1-1返回格式为 2017-1-1 23:59:00
	 * 
	 * @param dateString
	 * @return
	 */
	public static String getThisDay(String dateString) {

		// 1将获取的dateformart
		Date date = parseDate(dateString);
		return formatDate(date, "yyyy-MM-dd 23:59:00");
	}

	/**
	 * 获取当前日期前几天的日期
	 * 
	 * @Author keeny
	 * @Title: getBeforeDate
	 * @Description: 获取当前日期前几天的日期
	 * @param @param
	 *            beforeDays
	 * @param @return
	 *            设定参数
	 * @return String 返回类型
	 */
	public static String getBeforeDate(Integer beforeDays) {
		Date dNow = new Date(); // 当前时间
		Date dBefore = new Date();
		Calendar calendar = Calendar.getInstance(); // 得到日历
		calendar.setTime(dNow);// 把当前时间赋给日历
		calendar.add(Calendar.DAY_OF_MONTH, -beforeDays); // 设置为前几天
		dBefore = calendar.getTime(); // 得到前几天的时间
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // 设置时间格式
		String beforeDateStr = sdf.format(dBefore); // 格式化前几天日期

		return beforeDateStr;
	}

	/**
	 * 
	 * @Author 刘伟
	 * @Title: getBeforeMonthDate
	 * @Description: 获取当前日期前几月的日期
	 * @param @param
	 *            beforeMonths
	 * @param @return
	 *            设定参数
	 * @return String 返回类型
	 */
	public static Date getBeforeMonthDate(Integer beforeMonths) {
		Date dNow = new Date(); // 当前时间
		Date dBefore = new Date();
		Calendar calendar = Calendar.getInstance(); // 得到日历
		calendar.setTime(dNow);// 把当前时间赋给日历
		calendar.add(Calendar.MONTH, -beforeMonths);// 得到前3个月
		dBefore = calendar.getTime(); // 得到前几天的时间
		return dBefore;
	}

	/**
	 * 获取之后的日期
	 * 
	 * @return
	 */
	public static String getAfterDate(Integer afterDays) {
		return getBeforeDate(-afterDays);
	}

	/**
	 * 字符串转换成日期
	 * 
	 * @param str
	 * @return date
	 */
	public static Date strToDate(String str) {

		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		Date date = null;
		try {
			date = format.parse(str);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return date;
	}

	// 获取本周的开始时间
	public static Date getBeginDayOfWeek() {
		Date date = new Date();
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
		if (dayofweek == 1) {
			dayofweek += 7;
		}
		cal.add(Calendar.DATE, 2 - dayofweek);
		return getDayStartTime(cal.getTime());
	}

	// 获取本周的结束时间
	public static Date getEndDayOfWeek() {
		Calendar cal = Calendar.getInstance();
		cal.setTime(getBeginDayOfWeek());
		cal.add(Calendar.DAY_OF_WEEK, 6);
		Date weekEndSta = cal.getTime();
		return getDayEndTime(weekEndSta);
	}

	// 获取某个日期的开始时间
	public static Timestamp getDayStartTime(Date d) {
		Calendar calendar = Calendar.getInstance();
		if (null != d)
			calendar.setTime(d);
		calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 0,
				0, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return new Timestamp(calendar.getTimeInMillis());
	}

	// 获取某个日期的结束时间
	public static Timestamp getDayEndTime(Date d) {
		Calendar calendar = Calendar.getInstance();
		if (null != d)
			calendar.setTime(d);
		calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 23,
				59, 59);
		calendar.set(Calendar.MILLISECOND, 999);
		return new Timestamp(calendar.getTimeInMillis());
	}

	// 获取本月的开始时间
	public static Date getBeginDayOfMonth() {
		Calendar calendar = Calendar.getInstance();
		calendar.set(getNowYear(), getNowMonth() - 1, 1);
		return getDayStartTime(calendar.getTime());
	}

	// 获取本月的结束时间
	public static Date getEndDayOfMonth() {
		Calendar calendar = Calendar.getInstance();
		calendar.set(getNowYear(), getNowMonth() - 1, 1);
		int day = calendar.getActualMaximum(5);
		calendar.set(getNowYear(), getNowMonth() - 1, day);
		return getDayEndTime(calendar.getTime());
	}

	// 获取今年是哪一年
	public static Integer getNowYear() {
		Date date = new Date();
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		return Integer.valueOf(gc.get(1));
	}

	// 获取本月是哪一月
	public static int getNowMonth() {
		Date date = new Date();
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		return gc.get(2) + 1;
	}

	/**
	 * 获取某个月的第一天 @Author keeny @Title: getLastDayOfMonth @Description:
	 * 获取某个月的第一天 @param: @param date @param: @return @return: Date @throws
	 */
	public static Date getFirstDayOfMonth(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		Date firstDayOfMonth = calendar.getTime();
		return firstDayOfMonth;
	}

	/**
	 * 获取某个月的最后一天 @Author keeny @Title: getFirstDayOfMonth @Description:
	 * 获取某个月的最后一天 @param: @param date @param: @return @return: Date @throws
	 */
	public static Date getLastDayOfMonth(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.add(Calendar.MONTH, 1);
		calendar.add(Calendar.DAY_OF_MONTH, -1);
		Date lastDayOfMonth = calendar.getTime();
		return lastDayOfMonth;
	}

	/**
	 * @param args
	 * @throws ParseException
	 */
	public static void main(String[] args) throws ParseException {
		// System.out.println(formatDate(parseDate("2010/3/6")));
		// System.out.println(getDate("yyyy年MM月dd日 E"));
		// long time = new Date().getTime()-parseDate("2012-11-19").getTime();
		// System.out.println(time/(24*60*60*1000));
	}
}
